<?php
/***
 * model->find(first,array('contain'=>array(xxx)));
 * contain 指定级联查找的包含的模块
 */

App::uses('Validation', 'Utility');

/**
 * Class AppController
 *
 *  *
 * @property      AuthComponent $Auth
 * @property      CookieComponent $Cookie
 * @property      EmailComponent $Email
 * @property      PaginatorComponent $Paginator
 * @property      RequestHandlerComponent $RequestHandler
 * @property      SecurityComponent $Security
 * @property      SessionComponent $Session
 * @property      User $User
 * @property      Order $Order
 * @property AppModel $WxVote
 * @property AppModel $Baoming
 * @property AppModel $Qa
 * @property AppModel $UserAddress
 * @property UserSetting $UserSetting
 * @property AppModel $UserCate
 * @property AppModel $Cart
 * @property AppModel $Wx
 * @property 	  AppModel $WxActivity
 * @property 	  AppModel $SignedLog
 * @property 	  Shortmessage $Shortmessage
 * @property 	  AppModel $PraiseLog
 * @property 	  AppModel {$this->modelClass}
 * @property 	  AppModel {$modelClass}
 */
class AppController extends Controller {

    public $theme = 'default';
    public $viewClass = 'Miao';
    var $helpers = array(
        'Html', 'Section', 'Session', 'Form', 'Js', 'Hook' => array(),
    	'Swfupload','TagRelated',
    ); //'Oauth.OauthHook'
    public $__viewFileName = '';
    
    public $lazy = true;
    /*AuthComponent 移到UsersController(或其它需要控制访问权限的controller)中，AppController使用$this->Session->read('Auth.User')获取用户*/
    var $components = array(
    	'RequestHandler','Session', 
    	'Hook' => array( 'hooks'=> array('ScoreHook','WxHook') ),
    	'Weixin',
    	'Acl',
    );
    
    var $currentUser = null;
    var $insert_id;
 // 添加数据时。插入数据库的id
    var $WeiboUtil = null;
    var $role_ids = array();
 	/**
 	 * 编码转换方法，用于在简体与繁体互换，在dzstyle中执行转换操作。
 	 * @var string
 	 */
    var $convertCode = false;
    
 // 是否转码
    var $pageTitle;
    var $current_data_id;
    public $item = null;
    
    public $firephp_vars = array();

    // 自定义构造函数
    public function __construct($request = null, $response = null) {
        if ($request instanceof CakeRequest) {
            $this->name = $request['params']['controller'];
        }
        
        if (substr($_SERVER['REQUEST_URI'], 0, 11) == '/index.php/') {
            header('location:' . substr($_SERVER['REQUEST_URI'], 10));
            exit;
        }
        $request->webroot = '/';  // webroot目录直接放在根目录
        
        parent::__construct($request, $response);
        
        if (is_array($this->uses)  && !in_array($this->modelClass, $this->uses)) { // 修复子类uses未包含本模块的。 如继承WxAppController的各子类
        	if ($this->plugin) {
        		$this->plugin = Inflector::camelize($this->plugin);
        		array_unshift($this->uses, $this->plugin . '.' . $this->modelClass);
        	} else {
        		array_unshift($this->uses, $this->modelClass);
        	}
        }
        if( !empty($_SERVER['HTTP_AUTHORIZATION']) && substr($_SERVER['HTTP_AUTHORIZATION'],0,6) == 'Token ' ) {
            $this->Components->disable('Session');//手机或其它登录不启用Session
            $this->Session = null;
        }

	}
    
    public function beforeFilter() {
        
    	// $this->_international();

    	$postStr = file_get_contents('php://input', 'r');
    	//提交的内容为解析为正常json时，将内容合并到$_REQUEST变量中
    	if( !empty($postStr) ) { $arr = json_decode($postStr,true); if($arr) {$_REQUEST = array_merge($_REQUEST,$arr); }}
    	
    	$referer = $_SERVER['HTTP_REFERER'] ? $_SERVER['HTTP_REFERER'] : $_REQUEST['referer'];

    	//    	print_r($_SERVER);
    	if(isset($_SERVER['HTTP_AUTHORIZATION']) && substr($_SERVER['HTTP_AUTHORIZATION'],0,6) == 'Token '){
			$token = substr($_SERVER['HTTP_AUTHORIZATION'],6);
            $this->loadModel('SignToken'); //用户app登录Token
            $signtoken = $this->SignToken->getToken($token);
            if(!empty($signtoken)){
            	$uid = $signtoken['SignToken']['id'];
            	$this->loadModel('User');
                $userinfo = $this->User->getUserInfo($uid);
                $this->currentUser = $userinfo['User'];
			}
			else{
            	echo json_encode(array('ret'=>-133009,'msg'=> 'token expired.'));
            	exit;
			}
		}
    	elseif( !empty($_REQUEST['sign']) && !empty($_REQUEST['session_id']) && !empty($_REQUEST['timestamp'])  ) { //app端加密登录设置session_id
    	    
    	    $timestamp = $_REQUEST['timestamp'];
    	    if( strlen($_REQUEST['timestamp']) > 10 ) { // 毫秒的时间，转成秒
    	        $timestamp = substr($_REQUEST['timestamp'],0,10);
    	    }
    	    
    	    if( (time() - $timestamp) < 3600 ){
    	        $salt = Configure::read('User.sms_salt');
    	        if( $salt && $_REQUEST['sign'] == md5( $_REQUEST['timestamp'].$_REQUEST['session_id'].$salt ) ){
    	            $this->Session->id( $_REQUEST['session_id'] ); // app接口中传入session_id    	            
    	            if( !empty($_REQUEST['check_session']) ) {
    	            	$user_id = $this->Session->read('Auth.User.id');
    	            	if($user_id) {
    	            		$this->loadModel('User');
    	            		$userinfo = $this->User->getUserInfo($user_id);
    	            		if($userinfo['User']['status'] == -1 || $this->Session->read('Auth.User.mobile') != $userinfo['User']['mobile'] ) {
                                $user_id = 0; //状态为-1或者手机号已变更,置空$user_id， 返回-133109
							}
						}
    	            	if( !$user_id ) {
                            // session_id过期固定错误码 -133109
                            $successinfo = array('ret'=>-133109,'msg' => 'session_id已过期，登录失效' );
                            echo json_encode($successinfo);
                            exit;
						}
    	            }
    	        }
    	        else{
    	            unset($_REQUEST['sign']);
    	        }
    	    }
    	    else{
    	        unset($_REQUEST['sign']);
    	    }
    	}
    	elseif( !empty($_REQUEST['sign']) && !empty($_REQUEST['little_id']) &&  !empty($_REQUEST['open_id']) && !empty($_REQUEST['user_id']) && !empty($_REQUEST['timestamp']) &&  (time() - $_REQUEST['timestamp']) < 3600 ) { //小程序加密登录用户
    	    $this->loadModel('LittleApp');
    	    $app = $this->LittleApp->getItemById( $_REQUEST['little_id'] );
    	    $salt = $app['LittleApp']['secretkey'];
    	    if( $salt && $_REQUEST['sign'] == md5( $_REQUEST['timestamp'].$_REQUEST['little_id'].$_REQUEST['open_id'].$_REQUEST['user_id'].$salt )  ){
	            $this->loadModel('AppUser');
                $appuser = $this->AppUser->find('first',array(
                    'conditions'=> array('id' => $_REQUEST['user_id'],'app_id' => $_REQUEST['little_id'],'open_id' => $_REQUEST['open_id'] ),
                    'recursive' => -1,
                ));
	            if( !empty($appuser) ) {
	                $this->Session->write('Auth.AppUser',$appuser['AppUser']);
	            }
    	    }
    	    else{
    	        unset($_REQUEST['sign']);
    	    }
    	}
    	else if( $_GET['appkey'] && $_GET['token'] && $_GET['sign'] && $referer ) { // 编辑器样式授权
	        $host_info = parse_url($referer);
	        $this->loadModel('Appkey');
	        $appinfo = $this->Appkey->find('first',array(
	            'conditions' => array(
	               'appkey' => $_GET['appkey'],
	            ),
	        ));
	        $this->set('appinfo',$appinfo);
	        // 对于企业用户，加载企业用户收藏的通用样式，还可以加载用户自己单独收藏的样式。
	        if(!empty($appinfo) && !empty($appinfo['Appkey']['domain'] ) ) {
	            
	            $star_host = $host = $host_info['host'];
	            $hostchars = explode('.',$host);
	            if(count($hostchars) > 2) {
	                $hostchars[0] = '*';
	                $star_host = implode('.',$hostchars);
	            }
                $domains = explode("\r\n",$appinfo['Appkey']['domain']);
                if(in_array($host_info['host'],$domains) || in_array($star_host,$domains) ){
                    $appkey_user_id = $appinfo['Appkey']['creator'];
                    $this->set('appkey_user_id',$appkey_user_id);
                    // 企业会员传入了绑定的会员信息。
                    $this->loadModel('Token');
                    $tokeninfo = $this->Token->find('first',array(
                        'conditions' => array(
                            'token' => $_GET['token'],
                        ),
                    ));
                    if( !empty($tokeninfo) ) {
                        $sign = md5($_GET['token'].$tokeninfo['Token']['ecrypt_key'].$_GET['ts']);
                        // 校验通过，则设置用户的编号
                        if( $sign == $_GET['sign'] ) {
                            $this->loadModel('User');
                            $user = $this->User->getUserInfo( $tokeninfo['Token']['creator'] );
                            /** 直接登录用户 **/
                            if( !empty($user) ){
                                $this->Session->write('Auth.User',$user['User']);
                            }
                        }
                    }
                    else{
                        $this->Session->write('Auth.User', array('id'=> $appkey_user_id) );
					}
                }
	        }
	        
	    }
	    
    	//load_lang('default'); // 加载默认语言
    	


    	if(!Configure::read('Site.status')){
    		$this->layout = 'maintain';
    		$this->autoRender = false;
    		// 503——服务器过载或暂停维修
    		header('HTTP/1.1 503 Service Temporarily Unavailable');
    		header('Status: 503 Service Temporarily Unavailable');
    		echo $this->render();
    		exit;
    	}
    	
    	//strpos($_SERVER['HTTP_USER_AGENT'],"MicroMessenger")!==false;
    	// ipad时，使用PC网页,不认为是移动窄屏设备
    	$this->request->addDetector('iPad', array('env' => 'HTTP_USER_AGENT', 'options' => array('iPad')));
    	$this->request->addDetector('weixin', array('env' => 'HTTP_USER_AGENT', 'options' => array('MicroMessenger')));

    	if(get_class($this->Session) == 'SessionComponent'){ //App时，不起用Session.需要判断是否有Session对象
            if( !$this->request->is('iPad') && ($this->RequestHandler->isMobile() || $_GET['is_mobile']==1)){
                define('IS_MOBILE',true);
                $this->set('is_mobile',true);
                $this->theme = Configure::read('Site.mobile_theme');
                $this->theme = $this->theme?$this->theme:'3g';
            }
			elseif($this->Session->read('theme')){
                $this->theme = $this->Session->read('theme');
            }
            else{
                $this->theme = Configure::read('Site.theme');
            }

            if($_GET['theme']){
                $this->theme=$_GET['theme'];
                $this->Session->write('theme',$this->theme);
            }
            $this->currentUser = $this->Session->read('Auth.User');

            /** 管理员登录时，直接通过邮箱登录制定用户查看状态，方便测试调试数据 **/
            if( $this->Session->read('Auth.Staff.id') ) {

                Configure::write('debug',1); //开启测试模式，数据库模板修改实时更新

                if( $_GET['view_email'] || $_GET['view_uid'] ) {
                    $this->loadModel('User');
                    if($_GET['view_email']) {
                        $user = $this->User->getUserByEmail( $_GET['view_email'] );
                    }
                    else if($_GET['view_uid']) {
                        $user = $this->User->getUserInfo( $_GET['view_uid'] );
                    }
                    /** 直接登录用户 **/
                    if( !empty($user) ){
                        $this->Session->delete('User');//记录了用户的授权微信公众号缓存
                        $this->Session->write('Auth.User',$user['User']);
                    }
				}
            }
            // 无Session，且有Cookie登录信息时，解析cookie生成信息。否则忽略cookie，防止每次都要消耗性能解密cookie。
            // 跳转至login进行登录，便于登录积分处理等统一处理。
            // 其余时间使用session。
            if( !$this->Session->read('Auth.User.id') && empty($_POST) && isset($_COOKIE['MIAOCMS']) && $_COOKIE['MIAOCMS']['Auth']['User']){
                if( !isset($_REQUEST['lck']) && !in_array($this->action,array('login','logout','register') ) && strtolower($this->plugin) != 'oauth' ) {
                    $current_url = $this->request->here(); //增加get参数
                    header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
                    header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
                    header("Pragma: no-cache");
                    $this->redirect('/users/login?lck=1&referer='.urlencode($current_url));
                }
            }
		}

    	if( !empty($this->currentUser) ){
    	    if( !is_array($this->currentUser['role_id']) ) {
    	        $this->currentUser['role_id'] = array_filter(explode(',',$this->currentUser['role_id']));
    	    }
    		if( !empty($this->currentUser['Role']) ) {
    			foreach($this->currentUser['Role'] as $role) {
    			    if( !in_array($role['id'],$this->currentUser['role_id']) ){
    			        $this->currentUser['role_id'][] = $role['id'];
    			    }
    			}
    		}
    		
    		$this->Hook->loadhook('ScoreHook'); //对已登录用户，加载积分钩子
    		
    		if( in_array($this->action,array('view','anony','index','lists')) ){
    		    // 仅对已登录用户，未登录的可能会记录auth.redirect等
    		    session_write_close(); // 对于不会出现session赋值的操作，直接结束session锁的占用，
    		}
    		
    	}
    	
    	if (Configure::read('Site.openStatic')){
    		App::uses('HtmlCache', 'Lib');
    		$content = HtmlCache::getfile($this->request->here);
    		if(!empty($content)){
    			$etag = md5($content);
    			if(isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH']==$etag){
    				Header("HTTP/1.0 304 Not Modified");
    			}
    			header("Pragma: public");
    			header("Cache-Control: max-age=31536000");
    			header("Expires: ".gmdate("D, d M Y H:i:s", time()+31536000)."  GMT");
	    		header('Content-Type:text/html; charset=UTF-8');
	    		header('ETag: ' . $etag);
	    		echo $content;
	    		echo '<!-- get from static file cache. -->';
	    		exit;
    		}
    	}
    	/*elseif( empty($this->currentUser['id']) && $this->action == 'view' && empty($_POST) && empty($_REQUEST['novcache']) && php_sapi_name()!=='cli' ) { //未登录用户直接缓存返回
    	    $etag = 'anony_'.md5($_SERVER['HTTP_HOST'].'_'.$this->theme.'_'.$_SERVER['REQUEST_URI']);
    	    $content = Cache::read($etag,'filecache');
    	    if( $content !== false ) {
    	        echo $content;
    	        echo '<!-- get from cache. -->';
    	        exit;
    	    }
    	}*/

//        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
//        header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
//        header("Pragma: no-cache");
    }

    public function afterFilter() {
        if($_GET['output']=='pdf'){
        	$html = $this->response->body();
        	$file_name = urlencode($this->request->here);
        	file_put_contents(TMP.$file_name, $html);
        	// 使用wkhtmltopdf命令导出pdf
        	$ret =system("wkhtmltopdf ".(TMP.$file_name)." ".(TMP.$file_name).".pdf",$retval); 
        	if($ret!==false){
        		//header('Content-Type:application/pdf');
        		header("Content-Type: application/force-download");
        		header("Content-Disposition: attachment; filename=".basename($this->request->here).'.pdf');
        		echo file_get_contents((TMP.$file_name).".pdf");
        	}
        	else{
        		echo $retval;
        	}
        	exit;
        }
        
        if( $_REQUEST['outcode'] == 'gbk' ) {
            $html = $this->response->body();
            App::uses('Charset', 'Lib');
            $html = Charset::utf8_gbk($html);
            $this->response->body($html);
        }
    	
    	if (Configure::read('Site.openStatic') && $this->modelClass!='Category' && in_array($this->request->params['action'], array('view'))) {
            $html = $this->response->body();
            if (substr($this->request->here, -5) == '.html' && empty($this->request->query)) {
                // when action is view or index,write html cache file on the server.
                // 无html后缀的静态文件在浏览器中无法显示成网页
                App::uses('HtmlCache', 'Lib');
                HtmlCache::writefile($this->request->here, $html);
            }
        }
        /*elseif( empty($this->currentUser['id']) && $this->name=='Categories'  && $this->action == 'view'  && empty($_POST) && php_sapi_name()!=='cli'  ){
            // 加入theme，手机与pc需要缓存不同的内容.
            // 将缓存写入文件系统中，阿里云OCS取出数据每秒钟有流量限制，大的数据缓存不保存到OCS中
            $etag = 'anony_'.md5($_SERVER['HTTP_HOST'].'_'.$this->theme.'_'.$_SERVER['REQUEST_URI']);            
            $html = $this->response->body();
            Cache::write($etag, $html,'filecache');
        }*/
    }
    
	/**
     * //当含语言的参数时，设置base追加locale的内容，当传入locale为默认内容时，跳转去除locale参数。
     */
    private function _international(){
    	
    	if (!empty($this->request->params['locale']) && $this->request->params['locale'] != Configure::read('Site.language')) {
    		
    		//当含语言的参数时，设置base追加locale的内容，
    		if(in_array($this->request->params['locale'],array('zh-cn','zh-tw','en-us')))
    		{
	    		if(strpos($this->request->base,$this->request->params['locale'])===false){ //判断一次，防止requestAction重复添加
	    			$this->request->base = $this->request->base.'/'.$this->request->params['locale'];
	    		}
	    		define('APPEND_LOCALE_BASE', true);
	
	    		if($this->request->params['locale']=='zh-tw'){
	    			Configure::write('Site.language','zh-cn');
	    			$this->convertCode = 'g2b';//默认版本为简体，看繁体版本时，需要将简体转繁体显示，
	    			$this->locale = 'zh-tw';
	    		}
	    		elseif($this->request->params['locale']=='zh-cn' && Configure::read('Site.language')=='zh-tw'){
	    			Configure::write('Site.language','zh-tw');
	    			$this->convertCode = 'b2g';//默认版本为繁体，看简体版本时，需要将繁体转简体显示，
	    			$this->locale = 'zh-cn';
	    		}
	    		else{//非中文时，才修改语言版本。
	    			Configure::write('Site.language', $this->request->params['locale']);
	    			$this->locale = $this->request->params['locale'];
	    		}
	    		
	    		//$cache_prefix = APP_DIR.'_'.$this->request->params['locale'].'_dft_';
	    		$cache_prefix = APP_DIR.'_dft_';
	    		if(defined('SAE_MYSQL_DB')){// SAE区分各版本的缓存，不互相冲突
	    			$cache_prefix = $_SERVER['HTTP_APPVERSION'];
	    		}
	    		// 将语言版本加到缓存前缀中，防止不同语言版本的内容缓存出现交叉错乱
	    		Cache::config('default',array('prefix' => $cache_prefix));
    		}
    		else{ // 不支持的语言忽略
    			unset($this->request->params['locale']);
    			$this->locale = null;
    		}
    	}
    	elseif (!empty($this->request->params['locale'])) {
    		$this->locale = Configure::read('Site.language');
    		// 当传入locale为默认内容时，跳转去除locale参数。
    		// [REQUEST_URI] => /MIAOCMS/trunk/zh-cn/?helo
    		$url = str_replace($this->request->params['locale'],'',$this->request->url);
	    	$url = str_replace('//', '/', $url);
	    	if($url != $this->request->url && $this->locale.$url != $this->request->url){
	    		$this->redirect($url);
	    	}
	    	unset($this->request->params['locale']);
    	}
    	else{
    		$this->locale = Configure::read('Site.language');
    	}
    }
    

    public function beforeRender() {
    	if (!empty($this->request->params['locale'])) {
    		// 当传入locale为默认内容时，跳转去除locale参数。
    		// [REQUEST_URI] => /MIAOCMS/trunk/zh-cn/?helo
    		$url = str_replace($this->request->params['locale'],'',$this->request->url);
    		$url = str_replace('//', '/', $url);
    		$this->set('currentUrl',$url);
    	}
    	else{
    		$this->set('currentUrl', $this->request->url);
    	}
    	
    	$this->set('locale', strtolower($this->locale));
    	$this->set('basedir', $this->request->base);
    	$this->set('site_cate_id',$GLOBALS['site_cate_id']);
    	
    	$site_info = Configure::read('Site');
    	$this->set('site', $site_info);

        $reserve_shopids = explode(',',Configure::read('Order.reserve_shopids'));
        $this->set('reserve_shopids',$reserve_shopids);

    	$this->set('current_user_id', $this->currentUser['id']);
        $this->set('CurrentUser', $this->currentUser);
        $this->set('pageTitle', htmlspecialchars($this->pageTitle));
        
        if($this->request->is('weixin') || !empty($_REQUEST['is_weixin'])){
        	$this->set('isWeixin',true);
        }
        
        if ($this->request->is('ajax') || isset($_REQUEST['inajax'])) {
        	// ajax 操作
        	$this->layout = 'ajax';
        }
        
        $query_params = '';
        if(!empty($this->request->query)){
        	$query_params = http_build_query($this->request->query);
        }
        
        if(defined('APPEND_LOCALE_BASE')){
        	$current_url = str_replace($this->locale.'/','',$this->request->webroot.$this->request->url).($query_params?'?'.$query_params : '');
        }
        else{
        	$current_url = $this->request->webroot.$this->request->url.($query_params?'?'.$query_params : '');
        }
        if(empty($current_url)) $current_url = '/';
        
		// view时，有current_data_id。
        $this->set('current_url', $current_url);
        $this->set('current_model', $this->modelClass);
        $this->set('current_controller', $this->request->params['controller']);
        $this->set('current_action', $this->action);
        $this->set('current_pass', $this->request->params['pass']);
        $this->set('current_named', $this->request->params['named']);
    }

    protected function _getParamVars($name,$default='') {
        $val = '';
    	if( isset($_REQUEST[$name]) ){
    	    $val = $_REQUEST[$name];
    	}elseif (isset($this->request->query[$name])) {
        	$val = $this->request->query[$name];
        }elseif (isset($this->request->params['named'][$name])) {
            $val = $this->request->params['named'][$name];
        }elseif (isset($this->request->params[$name])) {
            $val = $this->request->params[$name];
        }else{
        	return $default;
        }
        return $val;
    }

    public function valifiled($field='') {
        // 直接输出，jsonencode，不需要调用模板
        $this->autoRender = false;
        $modelClass = $this->modelClass;
        //往model中注入值，否则无法验证
        $this->{$modelClass}->set($this->data);
        // 只验证提交过来的单个字段，或几个字段
        $errors = $this->{$modelClass}->invalidFields(array('fieldList' => array_keys($this->data[$modelClass])));
        //$errors = $this->{$modelClass}->invalidFields();
        echo json_encode($errors);
    }
    
    public function ip_stat($id){
    	$model = $this->modelClass;
    	$this->loadModel($model);    	
    	$datainfo = $this->{$model}->find('first', array(
    			'conditions' => array('id' => $id, 'creator' => $this->currentUser['id']),
    			'recursive' => -1,
    	));
    	if (empty($datainfo)) {
    		throw new ForbiddenException(__('You cannot edit this data'));
    	}
    	
    	$page = $_REQUEST['page'] ? $_REQUEST['page'] : 1;
    	$limit = 30;
    	$this->loadModel('Ipview');
    	$ipviews = $this->Ipview->find('all',array(
    			'conditions'=> array('model'=>$model,'data_id'=>$id),
    			'order' => 'id desc',
    			'limit' => $limit,
    			'page' => $page,
    	));
    	$this->set('id',$id);
    	$this->set('ipviews',$ipviews);
    }
    
    public function ip_stat_log($id,$date){
    	$model = $this->modelClass;
    	$this->loadModel($model);
    	$datainfo = $this->{$model}->find('first', array(
    			'conditions' => array('id' => $id, 'creator' => $this->currentUser['id']),
    			'recursive' => -1,
    	));
    	if (empty($datainfo)) {
    		throw new ForbiddenException(__('You cannot edit this data'));
    	}
    	
    	$page = $_REQUEST['page'] ? $_REQUEST['page'] : 1;
    	$limit = 100;
    	$this->loadModel('IpviewLog');
    	$ipviews = $this->IpviewLog->find('all',array(
    			'conditions'=> array('model'=>$model,'data_id'=>$id,'created' => $date),
    			'order' => 'id desc',
    			'limit' => $limit,
    			'page' => $page,
    	));
    	$this->set('id',$id);
    	$this->set('ipviews',$ipviews);
    }

    protected function view($slug) {
    	$modelClass = $this->modelClass;

    	if ( !$this->RequestHandler->accepts('json') && !$this->request->is('ajax') && !isset($_REQUEST['inajax'])) {//非ajax与json请求时，才进行域名限制跳转
        	$view_domain = Configure::read($modelClass.'.view_domain');
        	if( $view_domain ) {
        	   $url_info = parse_url($view_domain);
        	   if( strpos($_SERVER['HTTP_HOST'],$url_info['host']) === false){
            	    $url = $this->request->here();
//            	    CakeLog::debug("app::view view_domain direct. model:{$modelClass}  http_host ".$_SERVER['HTTP_HOST']." config host ".$view_domain);
            	    header('Location: '.$view_domain.$url);
        	       exit;
        	   }
        	}
    	}

    	if (empty($slug)) {
            $slug = $this->_getParamVars('slug');
        }
        if (empty($id)) {
            $id = $this->_getParamVars('id');
            if (empty($id)) {
                $id = intval($slug);
            }
        }
    	$this->{$modelClass}->recursive = 1; // 显示时，查询出相关联的数据。
    	
        if (!empty($slug) && $slug != strval(intval($slug))) {
            $this->item = $this->{$modelClass}->find('first', array(
                    'conditions' => array(
                        $modelClass.'.slug' => $slug
                    ),
            		'recursive' => 1,
            ));
        } elseif ($id) {
            $this->item = $this->{$modelClass}->find('first', array(
                    'conditions' => array(
                         $modelClass.'.id' => $id
                    ),
            		'recursive' => 1,
            ));
        } else {
            $this->redirect('/');
        }
        
        $this->loadModel('Favorite');
        $favorited = $this->Favorite->find('first',array(
            'conditions' => array(
                'model' => $modelClass,
                'data_id' => $id,
                'creator_id' => $this->currentUser['id'],
            )
        ));
        $this->set('favorited',$favorited);
        
        
        $this->__loadFormValues($modelClass,$this->item[$modelClass]['id']);
        if(!empty($this->data['Uploadfile'])){
            $this->item['Uploadfile'] = $this->data['Uploadfile'];
        }

        if ( empty($this->item) ) {
            $url = $this->referer();
            if (empty($url))
                $url = '/';
            throw new NotFoundException();
        }
        $this->current_data_id = $this->item[$modelClass]['id'];
        
        //$this->loadModel('Uploadfile');
    	//$this->item['Uploadfile'] = $this->Uploadfile->find('all',array(
        		// 'conditions'=> array(
        		// 		'modelclass'=>$modelClass,
        		// 		'data_id'=> $this->current_data_id
        		// 	),
        		// ));
        		
        $this->set('upload_files', $this->item['Uploadfile']);
        
        
        $record_type = Configure::read($modelClass.'.record_type');
        $viewLog = array();
        
        if(
        	empty($record_type) //未设置
        	|| ($record_type & 0x01) && !defined('IS_MOBILE')  //电脑端
        	|| ($record_type & 0x02) && defined('IS_MOBILE') ) //移动端
        {

        	if( Configure::read($modelClass.'.ip_view_nums')){// 记录日IP访问次数
        		$this->loadModel('Ipview');$this->loadModel('IpviewLog');
        		 
        		$date = date('Y-m-d');
        		 
        		$ip = $this->request->clientIp();
        		$viewLog = $this->IpviewLog->find('first',array(
        				'conditions' => array('ip'=>$ip,'model' => $modelClass,'data_id' => $this->current_data_id,'created' => $date ),
        		));
        		 
        		if(empty($viewLog)){ // 新访问        	
        			$this->IpviewLog->save(array(
        					'ip'=>$ip,
        					'model' => $modelClass,
        					'data_id' => $this->current_data_id,
        					'created' => $date ,
        					'view_nums' => 1,
        			));
        	
        			$dayView = $this->Ipview->find('first',array(
        					'conditions' => array('model' => $modelClass,'data_id' => $this->current_data_id ,'created' => $date ),
        			));
        			if($dayView){
        				$this->Ipview->updateAll(array('view_nums'=>'view_nums+1'),array('id' => $dayView['Ipview']['id'] ));
        			}
        			else{
        				$this->Ipview->save(array(
        						'model' => $modelClass,
        						'data_id' => $this->current_data_id ,
        						'created' => $date,
        						'view_nums'=>1,
        				));
        			}
        	
        		}
        		else{	// 已访问过
        			$this->IpviewLog->updateAll(array('view_nums'=>'view_nums+1','updated'=>'CURRENT_TIMESTAMP'),array('id' => $viewLog['IpviewLog']['id'] ));
        		}
        	}
        	
        	// ip在5分钟内无访问时，记录次数；否则允许访问，但不记录次数
        	if(Configure::read($modelClass.'.view_nums') && ( empty($viewLog) || (time() - strtotime($viewLog['IpviewLog']['updated']) > 300) ) ) {// 记录访问次数
        		 
        		if(Configure::read($modelClass.'.open_redis')) {
        			// 记录热门排行数据，月，周，日的排行
        			App::uses('RedisUtility', 'Utility');
        			RedisUtility::zIncrBy($modelClass.'Hot',1, $this->current_data_id);
        			RedisUtility::zIncrBy($modelClass.'HotMonth',1, $this->current_data_id);
        			RedisUtility::zIncrBy($modelClass.'HotWeek',1, $this->current_data_id);
        			RedisUtility::zIncrBy($modelClass.'HotDay',1, $this->current_data_id);
        			if($this->item[$modelClass]['wx_id']){ //公众号的热门文章
        				RedisUtility::zIncrBy('Wx'.$modelClass.'Hot_'.$this->item[$modelClass]['wx_id'],1, $this->current_data_id);
        				RedisUtility::zIncrBy('Wx'.$modelClass.'HotMonth_'.$this->item[$modelClass]['wx_id'],1, $this->current_data_id);
        				RedisUtility::zIncrBy('Wx'.$modelClass.'HotWeek_'.$this->item[$modelClass]['wx_id'],1, $this->current_data_id);
        				RedisUtility::zIncrBy('Wx'.$modelClass.'HotDay_'.$this->item[$modelClass]['wx_id'],1, $this->current_data_id);
        			}
        		}
        		else{
        		    $this->{$modelClass}->setVersionFlag(false);
        			$this->{$modelClass}->updateAll(
        					array($modelClass.'.view_nums' => $modelClass.'.view_nums+1'),
        					array($modelClass.'.id' => $this->current_data_id)
        			);
        		}
        	}
        }
        
        // modelSplitOptions,modelSplitSchema 在ModelSplitBehavior->afterFind中的生成
        $this->set($modelClass . 'SplitOptions', $this->{$modelClass}->modelSplitOptions);
        $this->set($modelClass . 'SplitSchema', $this->{$modelClass}->modelSplitSchema);

        // 若同时发布到了多个栏目，导航默认只算第一个栏目的
        $current_cateid = $this->item[$modelClass]['cate_id'];
        
        $this->loadModel('Category');
        $path_cachekey = 'category_path_'.$current_cateid;
        $navigations = Cache::read($path_cachekey);
        if ($navigations === false) {
        	$navigations = $this->Category->getPath($current_cateid);
        	Cache::write($path_cachekey, $navigations);
        }
        // 去除站点类型的节点
        while($navigations[0]['Category']['model']=='website'){
        	array_shift($navigations);
        }
        
        $this->set('top_category_id', $navigations[0]['Category']['id']);
        $this->set('top_category_name', $navigations[0]['Category']['name']);
        //seotitle  seodescription  seokeywords
        
        if (empty($this->item[$modelClass]['seokeywords'])) {
            $this->item[$modelClass]['seokeywords'] = $this->item[$modelClass]['name'];
        }
        if (empty($this->item[$modelClass]['seodescription'])) {
            $this->item[$modelClass]['seodescription'] = trim($this->item[$modelClass]['summary']);
        }


        $htmlPurifier = $this->Components->load('HtmlPurifier');
        $htmlPurifier->initPurifier();

        /*
        获取json的时候时候，不使用html_purifier，WxMsg编辑器加载编辑时是json加载写入的
        考虑将编辑加载的json移至/wx_msgs/edit/{id}.json
        */
        if( !empty($this->item[$modelClass]['content']) ){
            if( $this->lazy && empty($_REQUEST['nolazy']) ){
                $this->item[$modelClass]['content'] = lazyloadimg($this->item[$modelClass]['content']);
            }
            if($_REQUEST['lite']) {
                $this->item[$modelClass]['content'] = liteContent($this->item[$modelClass]['content']);
            }
            if (  !$this->request->is('ajax') ) {
                $this->item[$modelClass]['content'] = $htmlPurifier->filter($this->item[$modelClass]['content']);
            }
        }
		elseif( isset($this->item[$modelClass.'Content'])  && !empty($this->item[$modelClass.'Content']['content']) ){ //Such as ArticleContent
            if( $this->lazy && empty($_REQUEST['nolazy']) ){
                $this->item[$modelClass.'Content']['content'] = lazyloadimg($this->item[$modelClass.'Content']['content']);
            }
            if($_REQUEST['lite']) {
                $this->item[$modelClass.'Content']['content'] = liteContent($this->item[$modelClass.'Content']['content']);
            }
            if (  !$this->request->is('ajax') ) {
                $this->item[$modelClass . 'Content']['content'] = $htmlPurifier->filter($this->item[$modelClass . 'Content']['content']);
            }
        }

        if ($this->item[$modelClass]['seotitle']) {
            $this->pageTitle = $this->item[$modelClass]['seotitle'];
        } else {
            $this->pageTitle = $this->item[$modelClass]['name'];
        }
        if($this->item[$modelClass]['wx_id']  && $this->item['Wx']['name']){
            $this->pageTitle .= '-'.$this->item['Wx']['name'];
        }
        
        $this->set('wx_id', $this->item[$modelClass]['wx_id']);
        
        
        
        $this->set('seodescription', $this->item[$modelClass]['seodescription']);
        $this->set('seokeywords', $this->item[$modelClass]['seokeywords']);
        $this->set('id', $this->item[$modelClass]['id']);
        
        $this->set('current_cateid', $current_cateid);
        $this->set('use_stat', 'view'); // view action 使用统计，记录
        $this->set('current_data_id', $this->current_data_id);
        $this->set('current_model', $modelClass);
        $this->set('navigations', $navigations);
        $this->set($modelClass, $this->item);
        $this->set('ajax_data', array('data' => $this->item,'current_data_id'=>$this->current_data_id));
        
//         if( $this->currentUser['id'] == $this->item[$modelClass]['creator'] ) {
        	//避免通过json查看或盗取他人数据.不能在这直接这样限制仅添加者开放。不然编辑器模板内容json获取都不行了。
        	$this->set('_serialize', 'ajax_data');
//         }
        
    	$signPackage = $this->getSignPackage();
    	$this->set('signPackage',$signPackage);
    	
        $params = array($this->modelClass, $this->current_data_id);
        $this->Hook->call('viewItem', $params);

    }
    
    public function signed_list($id) {
        
        $modelClass = $this->modelClass;
        
        $page = $_REQUEST['page'] ? $_REQUEST['page'] : 1;
        $pagesize = $_REQUEST['limit'] ? $_REQUEST['limit'] : 100;
        
        $this->loadModel('SignedLog');
        $conditions = array(
                'model' => $modelClass ,
                'data_id' => $id,
            );
        if($_REQUEST['company_id']) {
            $conditions['company_id'] = $_REQUEST['company_id'];
        }
        
        if($_REQUEST['type'] == 'group') {
            $datalist = $this->SignedLog->find('all',array(
                'conditions'=> $conditions,
                'fields' => array('count(id) as nums','SignedLog.company_id'),
                'group' => 'company_id',
            ));
            $company_ids = array();
            foreach($datalist as $d) {
                $company_ids[] = $d['SignedLog']['company_id'];
            }
            $this->loadModel('Company');
            $companies = $this->Company->find('all',array('conditions'=>array(
                'id' => $company_ids,
            )));
            $arr = array();
            foreach($companies as $c){
                $arr[$c['Company']['id']] = $c['Company'];
            }
            foreach($datalist as &$d){
                $d['Company'] = $arr[ $d['SignedLog']['company_id'] ];
            }
        }
        else{
            $datalist = $this->SignedLog->find('all',array(
                'conditions'=> $conditions,
                'joins' => array(array(
                    'alias' => 'User',
                    'table' => 'users',
                    'type' => 'inner',
                    'conditions' => array('User.id=SignedLog.user_id'),
                )),
                'fields' => array('User.id','User.username','User.avatar','SignedLog.created'),
                'order' => 'SignedLog.id desc',
                'limit' => $pagesize,
                'page' => $page,
            ));
            
            $total = $this->SignedLog->find('count',array(
                'conditions' => $conditions,
            ));
            $this->set('datalist', $datalist);
            $this->set('total', $total);
            $rows = count($datalist);
            $page_navi = getPageLinks($total, $pagesize, $this->request, $page);
            $this->set('list_page_navi', $page_navi); // page_navi 在region调用中有使用，防止被覆盖，此处使用 list_page_navi
        }
        
        
        $this->ajax_data = $ajax_data = array(
            'ret' => 0,
            'total' => $total,
            'rows' => $rows,
            'datalist' => $datalist,
        );
        $this->set('ajax_data', $ajax_data);
        $this->set('_serialize', 'ajax_data');
    }
    
    /**
     * 签到
     * @param unknown $id
     */
    public function signed($id){
         
        if ( empty($this->currentUser['id'])  && !Configure::read($this->modelClass.'.allow_anonymous')  ) {
            echo json_encode(array('ret'=>-1,'msg' => __('please login') ));
            exit;
        }
    
        $modelClass = $this->modelClass;
    
        $this->loadModel('SignedLog');
        $signed = $this->SignedLog->find('first',array('conditions'=> array(
            'model' => $modelClass ,
            'user_id' => $this->currentUser['id'],
            'data_id' => $id,
        )));
         
        if(empty($signed)) {
            
            $company_id = $this->currentUser['default_company_id'] ? $this->currentUser['default_company_id'] : $this->currentUser['company_id'];
            $company_id = $company_id ? $company_id : $_REQUEST['company_id'];
            
            $this->{$modelClass}->updateAll(
                array($modelClass.'.signed_nums' => $modelClass.'.signed_nums+1'),
                array( $modelClass.'.id' => $id )
                );
            $this->SignedLog->save(array(
                'model' => $modelClass ,
                'user_id' => $this->currentUser['id'],
                'company_id' => $company_id,
                'data_id' => $id,
            ));
    
            echo json_encode(array('ret'=>0,'msg'=> 'Signed success.'));
        }
        else{
            echo json_encode(array('ret'=>0,'msg'=> 'Already signed'));
        }
        exit;
    }
    
    /**
     * 赞
     * @param unknown $id
     */
    public function praise_list($id){
         
        if ( empty($this->currentUser['id']) ) {
            echo json_encode(array('ret'=>-1,'msg' => __('please login') ));
            exit;
        }
        $this->loadModel('PraiseLog');
        
        $page = $_REQUEST['page'] ? $_REQUEST['page'] : 1;
        $pagesize = $_REQUEST['limit'] ? $_REQUEST['limit'] : 100;
        
        $modelClass = $this->modelClass;
        $conditions = array(
            'model' => $modelClass ,
            'data_id' => $id,
        );
        if($_REQUEST['company_id']) {
            $conditions['company_id'] = $_REQUEST['company_id'];
        }
        
        if($_REQUEST['type'] == 'group') {
            $datalist = $this->PraiseLog->find('all',array(
                'conditions'=> $conditions,
                'fields' => array('count(id) as nums','PraiseLog.score'),
                'group' => 'score',
            ));
        }
        else{
            $datalist = $this->PraiseLog->find('all',array(
                'conditions'=> $conditions,
                'joins' => array(array(
                    'alias' => 'User',
                    'table' => 'users',
                    'type' => 'inner',
                    'conditions' => array('User.id=PraiseLog.user_id'),
                )),
                'fields' => array('User.id','User.username','User.avatar','PraiseLog.created'),
                'order' => 'PraiseLog.id desc',
                'limit' => $pagesize,
                'page' => $page,
            ));
            $scores = array();
            foreach($datalist as $d) {
                if(isset($scores[ 's_'.$d['PraiseLog']['score'] ])) {
                    $scores[ 's_'.$d['PraiseLog']['score'] ]++;
                }
                else{
                    $scores[ 's_'.$d['PraiseLog']['score'] ] = 1;
                }
            }
            
            $total = $this->PraiseLog->find('count',array(
                'conditions' => $conditions,
            ));
            $page_navi = getPageLinks($total, $pagesize, $this->request, $page);
            $this->set('list_page_navi', $page_navi); // page_navi 在region调用中有使用，防止被覆盖，此处使用 list_page_navi
        }
        
        $this->set('datalist', $datalist);
        $this->set('total', $total);
        $rows = count($datalist);
        
        $this->ajax_data = $ajax_data = array(
            'ret' => 0,
            'total' => $total,
            'rows' => $rows,
            'scores' => $scores,
            'datalist' => $datalist,
        );
        $this->set('ajax_data', $ajax_data);
        $this->set('_serialize', 'ajax_data');
    }

    /**
     * 赞
     * @param unknown $id
     */    
    public function praise($id){
         
        $modelClass = $this->modelClass;
        
        if ( empty($this->currentUser['id']) && !Configure::read($modelClass.'.allow_anonymous') ) {
            echo json_encode(array('ret'=>-1,'msg' => __('please login') ));
            exit;
        }
        $praised = false;
        if( $this->currentUser['id'] ){
            $this->loadModel('PraiseLog');
            $praised = $this->PraiseLog->find('first',array('conditions'=> array(
                'model' => $modelClass ,
                'user_id' => $this->currentUser['id'],
                'data_id' => $id,
            )));
        }
         
        if(empty($praised)) {
    
            $this->{$modelClass}->updateAll(
                array($modelClass.'.praise_nums' => $modelClass.'.praise_nums+1'),
                array( $modelClass.'.id' => $id )
            );
            
            if ( $this->currentUser['id'] ) {
                $this->PraiseLog->save(array(
                    'model' => $modelClass ,
                    'user_id' => $this->currentUser['id'],
                    'score' => isset($_REQUEST['score']) ? intval($_REQUEST['score']) : 0,
                    'data_id' => $id,
                ));
            }
            echo json_encode(array('ret'=>0,'msg'=> '已成功点赞'));
        }
        else{
            echo json_encode(array('ret'=>-1,'msg'=> '已点过赞'));
        }
        exit;
    }
    
    public function getoptions(){
        $this->autoRender = false;
        $this->__loadFormValues($this->modelClass);
        foreach($this->viewVars as &$item) {
            if(is_array($item)) {
                foreach($item as $k => $val) {
                    if($k === '' ) {
                        unset($item[$k]);
                    }
                }
            }
        }
        $this->ajaxOutput($this->viewVars);
        exit;
    }

    public function add() {
        if ( empty($this->currentUser['id']) && !Configure::read($this->modelClass.'.allow_anonymous')  ) {
            
            if ($this->RequestHandler->accepts('json') || $this->request->is('ajax') || isset($_REQUEST['inajax'])) {
                $successinfo = array('ret'=>-1,'msg' => __('please login') );
                echo json_encode($successinfo);
                exit;
            }
            $this->set('referer',$this->request->here());
            $this->redirect('/users/login?referer='.$this->request->here());
        }
        
        $this->pageTitle = __('Add').__d('modelextend',$this->modelClass);

        $modelClass = $this->modelClass;
        
        
        if (!empty($this->data)) {
//         	foreach ($this->data[$modelClass] as &$item){
//          数据的数字处理到放到对应的model的beforeSave中，有的需要implode，有的可能多维数组需要json_encode等
//         		if(is_array($item)){
//         			$item = implode(',',$item); // 若提交的内容为数组，则使用逗号连接各项值保存到一个字段里
//         		}
//         	}
            $this->data[$modelClass]['creator'] = $this->currentUser['id'];
            $this->{$modelClass}->create();
            $this->{$modelClass}->set($this->data);
            if ( $this->{$modelClass}->saveAll($this->data) ) {
                $this->insert_id = $this->data[$modelClass]['id'] = $insert_id = $this->{$this->modelClass}->getLastInsertId();
                
                if(!empty($this->data['TagRelated'])){
                    $this->loadModel('TagRelated');
                    if(is_array($this->data['TagRelated']['tag_id']))  {
                        foreach($this->data['TagRelated']['tag_id'] as $tag_id) {
                            $this->TagRelated->create();
                            $this->TagRelated->save(array(
                                'tag_id' => $tag_id,
                                'relatedid'=> $insert_id,
                                'relatedmodel'=> $modelClass,
                            ));
                        }
                    }
                    else{
                        $this->TagRelated->create();
                        $this->TagRelated->save(array(
                            'tag_id' => $this->data['TagRelated']['tag_id'],
                            'relatedid'=> $insert_id,
                            'relatedmodel'=> $modelClass,
                        ));
                    }
                }
                
                if(!empty($this->data['Uploadfile'])){
                    $this->loadModel('Uploadfile');
                    foreach($this->data['Uploadfile'] as $k => $file){
                        if( is_array($file) &&  $file['id'] ) {
                            $this->Uploadfile->updateAll(array('data_id' => $insert_id),array('id'=>$file['id'] ));
                        }
                        elseif( is_array($file) ){  // data[Uploadfile][fieldname] => [1,2]
                            foreach($file as $fileid) {
                                $this->Uploadfile->updateAll(array('data_id' => $insert_id),array('id'=>$fileid ));
                            }
                        }
                        elseif($file){ //具体项非数组时，直接传入的id。主要用于app中传回文件信息。  如传入 data[Uploadfile] => [1,2]
                            $this->Uploadfile->create();
                            $fileinfo = array();
                            $fileinfo['id'] = $file;
                            $fileinfo['user_id'] = $this->currentUser['id']; //用于获取分表
                            $fileinfo['data_id'] = $insert_id;
                            // 只修改  data_id
                            $this->Uploadfile->save($fileinfo, true, array('data_id')); 
                        }
                    }
                }

                $referer = $this->data[$this->modelClass]['referer'] ? $this->data[$this->modelClass]['referer'] : ($_REQUEST['referer'] ? $_REQUEST['referer'] : '');
                if(empty($referer)) {
                    if($this->data[$modelClass]['model']){
                        $referer = Router::url( array('action' => 'view',$this->insert_id,'?'=>array('model'=>$this->data[$modelClass]['model'])) );
                    }
                    else{
                        $referer = Router::url( array('action'=>'view',$this->insert_id) );
                    }
                }

                if ($this->RequestHandler->accepts('json') || $this->request->is('ajax') || isset($_REQUEST['inajax'])) {
                    $this->autoRender = false;
                    $this->layout = false;
                    $tasks = array();
                    if( $referer !='false' && $referer!='#'){
                        $tasks[] = array('dotype'=>'location','url'=>$referer);
					}
                    $successinfo = array(
                    	'ret'=>0,
						'msg' => __('Add Success'),
						'data'=> $this->data,
						'tasks' => $tasks,
					);
                    echo json_encode($successinfo);
                    if($_REQUEST['return']) {
                        return true; // 子controller需要做其他的处理，返回。否则退出
                    }
                    exit; // 退出，否则ajax内容后，多出一个1
                }
                else{
                    if($_REQUEST['return']) {
                        return true;
                    }
                    else{
                        $this->redirect($referer);
                    }
                }
            } else {
                if ($this->RequestHandler->accepts('json') || $this->request->is('ajax') || isset($_REQUEST['inajax'])) {
                    $successinfo = array('ret'=>-1,'msg' => __('save error') );
                    echo json_encode($successinfo);
                    return false;;
                }
            }
        }
        else{
            $this->__loadFormValues($modelClass);
            if (is_array($this->request->query) && !empty($this->request->query)) {
            	foreach ($this->request->query as $k => $v) {
            		$this->data[$this->modelClass][$k] = $v;
            	}
            }
        }
    }

    public function mine(){
        $pagesize = intval(Configure::read($this->modelClass.'.pagesize'));
        if(!$pagesize){
            $pagesize = 12;
        }
        
        $this->pageTitle = __('My').__d('modelextend',$this->modelClass);
        
        if(empty($this->currentUser['id'])){
            $this->redirect('/users/login?referer='.urlencode($this->request->here()));
            exit;
        }
        
        $this->autoRender = true;
        
        $page = $_REQUEST['page'] ? $_REQUEST['page'] : 1;
        
        $conditions = getSearchOptions($_REQUEST, $this->modelClass);
        
        $schema = $this->{$this->modelClass}->schema();
        
        if( isset($schema['creator']) ) {
        	$conditions = array('creator' => $this->currentUser['id']);
        }
        elseif( isset($schema['user_id']) ){
        	$conditions = array('user_id' => $this->currentUser['id']);
        }
        else {
        	return false;
        }
        
        if( isset($schema['deleted']) ) {
            $conditions['deleted'] = $_REQUEST['deleted'] ? 1 : 0;
        }
        
        $fields = array();
        foreach ($schema as $key => $value) {
            
            if(isset($_REQUEST[$key]) && $key != 'type') {
                $conditions[$key] = $_REQUEST[$key];
            }
            
            if($value['type']=='text' && !in_array($this->modelClass,array('Signature','BotMessage')) ){
                continue;
            }
            $fields[] = $key;
        }
        
        
        $total = $this->{$this->modelClass}->find('count', array(
            'conditions' => $conditions,
            'recursive' => -1,
        ));
        
        $recursive = $_REQUEST['recursive'] ? $_REQUEST['recursive'] : -1;
        
        $datalist = $this->{$this->modelClass}->find('all', array(
                'conditions' => $conditions,
                'fields'=> $fields,
        		'limit' => $pagesize,
        		'page' => $page,
                'order'=>'id desc',
                'recursive' => $recursive,
        ));
        
        if($_REQUEST['type'] == 'select') {
            $this->__viewFileName = 'select';
        }
        
        

        $page_navi = getPageLinks($total, $pagesize, '/'.Inflector::tableize($this->modelClass).'/mine', $page);
        $this->set('datalist',$datalist);
        $this->set('page_navi', $page_navi);
        
        $this->set('ajax_data', array('datalist'=>$datalist,'total'=>$total,'page'=>$page,'page_navi'=>$page_navi));
        $this->set('_serialize', 'ajax_data');
    }

    function edit($id) {
        $modelClass = $this->modelClass;
        if (!$id) {
            throw new ForbiddenException('Error url');
        }
        
        $this->item = $datainfo = $this->{$this->modelClass}->find('first', array(
            'conditions' => array('id' => $id, 'creator' => $this->currentUser['id']),
            'recursive' => 1,
        ));
        if (empty($datainfo)) {
            throw new ForbiddenException(__('You cannot edit this data'));
        }

        if (!empty($this->data)) {
        	if( empty($this->data[$modelClass]['id']) ) {
        		$this->data[$modelClass]['id'] = $id;
        	}
            $this->autoRender = false;
            $this->data[$modelClass]['creator'] = $this->currentUser['id'];

            if ($this->{$this->modelClass}->saveAll($this->data)) {

                if(!empty($this->data['TagRelated'])){
                    $this->loadModel('TagRelated');
                    if(is_array($this->data['TagRelated']['tag_id']))  {
                        foreach($this->data['TagRelated']['tag_id'] as $tag_id) {
                            $this->TagRelated->create();
                            $this->TagRelated->save(array(
                                'tag_id' => $tag_id,
                                'relatedid'=> $id,
                                'relatedmodel'=> $modelClass,
                            ));
                        }
                    }
                    else{
                        $this->TagRelated->create();
                        $this->TagRelated->save(array(
                            'tag_id' => $this->data['TagRelated']['tag_id'],
                            'relatedid'=> $id,
                            'relatedmodel'=> $modelClass,
                        ));
                    }
                }
                
                if(!empty($this->data['Uploadfile'])){
                    $this->loadModel('Uploadfile');
                    foreach($this->data['Uploadfile'] as $k => $file){
                        if( is_array($file) &&  $file['id'] ) {
                            $this->Uploadfile->updateAll(array('data_id' => $id),array('id'=>$file['id'] ));
                        }
                        elseif( is_array($file) ){  // data[Uploadfile][fieldname] => [1,2]
                            foreach($file as $fileid) {
                                $this->Uploadfile->updateAll(array('data_id' => $id),array('id'=>$fileid ));
                            }
                        }
                        elseif($file){ //具体项非数组时，直接传入的id。主要用于app中传回文件信息。  如传入 data[Uploadfile] => [1,2]
                            $this->Uploadfile->create();
                            $fileinfo = array();
                            $fileinfo['id'] = $file;
                            $fileinfo['user_id'] = $this->currentUser['id']; //用于获取分表
                            $fileinfo['data_id'] = $id;
                            // 只修改  data_id
                            $this->Uploadfile->save($fileinfo, true, array('data_id'));
                        }
                    }
                }
                $resultinfo = array('ret'=>0,'msg' => __('Edit success'));
            } else {
                $resultinfo = array('ret'=>-1,'msg' => __('save failed'));
            }
            $successinfo = array('ret'=>0,'msg' => __('Edit success'), 'tasks' => array(array('dotype' => 'closedialog')));

            $redirect = $this->data[$this->modelClass]['referer'] ? $this->data[$this->modelClass]['referer'] : ($_REQUEST['referer'] ? $_REQUEST['referer'] : '');
            if(empty($redirect)){
                $redirect = Router::url(array('action'=>'view',$id));
            }
            if ($this->RequestHandler->accepts('json') || $this->request->is('ajax') || isset($_REQUEST['inajax'])) {
                $successinfo['tasks'][] = array('dotype'=>'location','url' => $redirect );
            	$this->ajaxOutput($successinfo);
            }
            $this->redirect($redirect);
        }
        else{
            $this->data = $datainfo; //加载数据到表单中            
            $this->set('id',$id);
            $this->__loadFormValues($modelClass);
        }
        $this->pageTitle = __('Edit '.$this->modelClass);
        $this->__viewFileName = 'add';
    }
    /**
     *
     * @param unknown $aco such as  'controllers/Uploadfiles'
     */
    protected function check_permition($aco){
    	if( $this->currentUser['id']) {
    		$role_ids = array();
    		$role_ids[] = 2; //普通注册组
    		if(is_array($this->currentUser['Role'])) {
    			foreach($this->currentUser['Role'] as $role) {
    				$role_ids[] = $role['id'];
    			}
    		}
    		if( $this->Acl->check(array('model'=>'Role','foreign_key'=> $role_ids),$aco) ){
    			return 1;
    		}
    	}
    	return 0;
    }
    
    public function delete($id){
        $this->autoRender = false;
        $this->autoLayout = false;
        if(empty($id)) {
            $id = $_REQUEST['id'];
        }
    	
    	$schema = $this->{$this->modelClass}->schema();
    	if(isset($schema['creator'])) {
    		$this->{$this->modelClass}->deleteAll(array('id' => $id, 'creator' => $this->currentUser['id']),true,true);
        	echo json_encode(array('ret'=>0,'msg'=> __('Delete Successfully')));
    	}
    	elseif(isset($schema['user_id'])) {
    		$this->{$this->modelClass}->deleteAll(array('id' => $id, 'user_id' => $this->currentUser['id']),true,true);
        	echo json_encode(array('ret'=>0,'msg'=> __('Delete Successfully')));
    	}
    	else{
    	    echo json_encode(array('ret'=>-1,'msg'=> __('Delete Error')));
    	}
    	exit;
    }
    
    function trash($ids = null) {
        if(is_array($_POST['ids'])&& !empty($_POST['ids'])){
            $ids = $_POST['ids'];
        }
        else{
            if (!$ids) {
                $this->redirect(array('action' => 'mine'));
            }
            $ids = explode(',', $ids);
        }
         
        $error_flag = false;
        $fields = array_keys($this->{$this->modelClass}->schema());
    
        $this->{$this->modelClass}->recursive = -1;
        foreach ($ids as $id) {
            if ( !intval($id) )
                continue;
    
            $data = array();
            $data['deleted'] = 1;
            if(in_array('published',$fields)){
                $data['published'] = 0;
            }
            $this->{$this->modelClass}->updateAll( $data, array($this->modelClass.'.id' => $id,'creator' => $this->currentUser['id']) );
        }
        echo json_encode(array('success'=> __('Trash success')));
        exit;
    }
    
    
    function restore($ids = null) {
        if(is_array($_POST['ids'])&& !empty($_POST['ids'])){
            $ids = $_POST['ids'];
        }
        else{
            if (!$ids) {
                $this->redirect(array('action' => 'index'));
            }
            $ids = explode(',', $ids);
        }
    
        foreach ($ids as $id) {
            if ( !intval($id) )
                continue;
            $data = array();
            $data[$this->modelClass]['id'] = $id;
            $data[$this->modelClass]['deleted'] = 0;
    
            if ( $this->{$this->modelClass}->save($data[$this->modelClass]) ) {
                $successinfo = array('success' => __('Restore success'));
            } else {
                $successinfo = array('error' => __('Restore error'));
            }
        }
        echo json_encode($successinfo);
        exit;
    }

    /**
     * 列表,不能开放lists方法随意显示数据列表，否则能访问的模块的数据都能被人查看到。
     * 特别是用户个人数据。会严重泄密事件
     */
    protected function lists() {
        $page = $this->_getParamVars('page');
        $rows = $_REQUEST['limit'] ? $_REQUEST['limit'] : 15;
        $order = $_REQUEST['sort'] ? $_REQUEST['sort'] : $this->modelClass.'.id desc';
        $joins = array();
        
        $conditions = getSearchOptions($_REQUEST,$this->modelClass);
        
        $schema = $this->{$this->modelClass}->schema();
        if( isset($schema['deleted']) ) {
            $conditions['deleted'] = 0;
        }
        
        if($_REQUEST['type'] == 'self') {
            $conditions[$this->modelClass.'.creator'] = $this->currentUser['id'];
        }
        else if( isset($schema['published']) ) {
            $conditions[$this->modelClass.'.published'] = 1;
        }
        $recursive = $_REQUEST['recursive'] > 0 ? 1 : -1;
        
        $find_type = in_array($_REQUEST['find'],array('list','threaded')) ? $_REQUEST['find'] : 'all';
        if( $_REQUEST['parent_id'] && $find_type == 'threaded' ) {
            $parent_item = $this->{$this->modelClass}->getItemById($_REQUEST['parent_id']);
            unset($conditions['parent_id'],$conditions[$this->modelClass.'.parent_id']);
            $conditions[$this->modelClass.'.left >'] = $parent_item[$this->modelClass]['left'];
            $conditions[$this->modelClass.'.right <'] = $parent_item[$this->modelClass]['right'];
        }
//         print_r($conditions);print_r($joins); echo $order;
        $datalist = $this->{$this->modelClass}->find($find_type, array(
            'conditions' => $conditions,
            'joins' => $joins,
            'limit' => $rows,
            'order' => $order,
            'page' => $page,
            'recursive' => $recursive,
        ));

        $total = $this->{$this->modelClass}->find('count',array(
            'conditions' => $conditions,
            'joins' => $joins,
        ));
        $this->set('modelClass', $this->modelClass);
        $this->set('region_control_name', Inflector::tableize($this->modelClass));
        $this->set('datalist', $datalist);
        $this->set('total', $total);

        $page_navi = getPageLinks($total, $rows, $this->request, $page);
        $this->set('list_page_navi', $page_navi); // page_navi 在region调用中有使用，防止被覆盖，此处使用 list_page_navi
        
        $fields = array_keys($schema);
        if($this->currentUser['id'] && in_array('favor_nums',$fields)){
            // favor_nums在列表显示字段范围内, 查询已收藏的列表
            $data_ids = array();
            foreach($datalist as $item){
                $data_ids[] = $item[$this->modelClass]['id'];
            }
             
            $this->loadModel('Favorite');
            $fovarited_list = $this->Favorite->find('list',array(
                'conditions'=>array(
                    'model' => $this->modelClass,
                    'data_id' => $data_ids,
                    'creator_id' => $this->currentUser['id'],
                ),
                'recursive' => -1,
                'fields' => array('id','data_id'),
            ));
            $this->set('fovarited_list',$fovarited_list);            
        }
        $this->ajax_data = $ajax_data = array(
            'ret' => 0,
            'total' => $total,
            'datalist' => $datalist,
        );
        
        if(!empty($fovarited_list)) {
            $ajax_data['fovarited_list'] = $fovarited_list;
        }
        
        $this->set('ajax_data', $ajax_data);
        $this->set('_serialize', 'ajax_data');
    }

    /**
     * 消息提醒
     * @param unknown $message
     * @param unknown $url
     * @param number $seconds
     * @param number $ret 返回的状态，0为成功，其余为失败
     * @return unknown
     */
	function __message($message, $url=null, $seconds=5,$ret = 0) {
    	@header('Content-Type:text/html; charset=UTF-8');
        if($this->request->params['return']){ // in controller::requestAction;
        	return $message;
        }
        else{
        	if ( !isset($_REQUEST['rethtml']) && ($this->RequestHandler->accepts('json') || $this->request->is('ajax') || isset($_REQUEST['inajax'])) ){
        		echo json_encode(array('ret'=>$ret,'msg'=>$message,'url'=>$url));
        	}
        	else{
        		if(empty($url)) {
        			$seconds = 999;
        		}
        		if($url === null) {
        			$url = 'javascript:history.back();';
        		}
        		
        		$this->set('message', $message);
        		$this->set('ret', $ret);
        		$this->set('seconds', $seconds);
        		
        		
        		$this->set('url', $url);
        		$this->__viewFileName = 'message';
        		$this->autoRender = false;
        		echo $this->render('message');
        	}
        	exit;
        }
    }
    
    protected function ajaxOutput($array){

        if( $this->Session ){
            $array['session_id'] = $this->Session->id();
            $this->Session->delete('Message.flash');
        }

        $json = json_encode($array);
        if($_GET['jsoncallback']){
            $this->response->type('application/x-javascript');
            $json = $_GET['jsoncallback'] . '(' . $json . ');';
        }
        else{
            $this->response->type('application/json');//; charset=UTF-8
        }

        //echo并 exit退出时，$this->Cookie信息未发出，cookie创建失败。
        // 使用response时，$this->Cookie会发送至浏览器
        $this->response->body($json);// response->send时，cookie.write才会生效
        $this->response->send();
        //$this->autoRender = false;
        exit;
    }

    function renderElement($element) {
		$this->viewClass='Miao'; //可能会被改成Json，需要强制指定
    	$this->View = $this->_getViewObject();
    	$response =  $this->render($element,false);
//     	var_dump($response);
    	if($response instanceof CakeResponse){
    		return $response->body();
    	}
    	return $response;
    }
    
    protected function getSignPackage() {
        // https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1421823488&token=&lang=zh_CN
        /**
         * 第三方平台开发者代替公众号使用JS SDK
         * 3、通过config接口注入权限验证配置，但在获取jsapi_ticket时，不通过公众号的access_token来获取，
         * 而是通过第三方平台的授权公众号token（公众号授权给第三方平台后，第三方平台通过“接口说明”中的api_authorizer_token接口得到的token），来获取jsapi_ticket，
         * 然后使用这个jsapi_ticket来得到signature，进行JS SDK的配置和开发。
         * 注意JS SDK的其他配置中，其他信息均为正常的公众号的资料（而非第三方平台的）。
         * @var Ambiguous $jsapiTicket
         */
        App::uses('WeixinUtility', 'Utility');
        if(empty(WeixinUtility::$appId)) {
            WeixinUtility::$appId = Configure::read('Weixin.AppId');
        }
        if(WeixinUtility::$appId) {
            $jsapiTicket = WeixinUtility::getJsApiTicket();
            
            // 注意 URL 一定要动态获取，不能 hardcode.
            $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
            $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
            
            $timestamp = time();
            $nonceStr = $this->createNonceStr();
            
            // 这里参数的顺序要按照 key 值 ASCII 码升序排序
            $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
            
            $signature = sha1($string);
            
            $signPackage = array(
                "appId"     => WeixinUtility::$appId,
                "nonceStr"  => $nonceStr,
                "timestamp" => $timestamp,
                "url"       => $url,
                "signature" => $signature,
                "rawString" => $string,
                "jsapiTicket" => $jsapiTicket
            );
            return $signPackage;
        }
        else{
            return array();
        }        
    }
    
    protected function createNonceStr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    /**
     * 加载表单选项值，默认值等。
     * 加载的值赋值到$this->request->data[$modelClass][$fieldname]中
     * @param  $modelClass 模块名称
     * @param  $id      数据id
     */
    protected function __loadFormValues($modelClass, $id = '') {
//      var_dump($this->{$modelClass});
        //$loadModelObj = null;
        $model_alias = $this->{$modelClass}->alias;
        if (isset($this->{$modelClass})) {
            $ext_schema = $this->{$modelClass}->getExtSchema();
        } elseif (isset($this->{$this->modelClass}->{$modelClass})) {
            $ext_schema = $this->{$this->modelClass}->{$modelClass}->getExtSchema();
        }
        
        $model_uploadfiles = false;

        foreach ($ext_schema as $k => $v) {
            if ($v['selectvalues']) {
                $selects = optionstr_to_array($v['selectvalues']);
                
                if ( $v['formtype'] == 'select' && $v['name'] != 'status' ) {
                    $newoptions = array('' => __('Please select'));
                }
                else{
                    $newoptions = array();
                }
                
                foreach ($selects as $ok => $ov) {
                    $newoptions[$ok] = $ov;
                }
                $fieldname = Inflector::variable(
                    Inflector::pluralize(preg_replace('/_id$/', '', $k))
                );
                $this->set($fieldname, $newoptions);
            }
            elseif ($id && $v['formtype'] == 'file') {

                //修改，字段为文件上传时。 从uploadfile模块中加载文件。 一个表可能有多个上传文件字段，只查询一次表。按字段将纪律分配到各项值。
                if($model_uploadfiles === false) {
                    $this->loadModel('Uploadfile');
                    /**传入user_id,查询分表的数据**/
                    $conditions = array('modelclass' => $modelClass, 'data_id' => $id);
                    if($this->item[$modelClass]['creator']){
                        $conditions['user_id'] = $this->item[$modelClass]['creator'];
                    }

                    $searchoptions = array(
                        'conditions' => $conditions, // 'fieldname' => $v['name'],
                        'order' => 'id asc',
                        'limit' => 100,
                        'page' => 1,
                        'fields' => array('id','data_id','fieldname','link','name','size','fspath','thumb','type','created'),
                    );
                    $model_uploadfiles = $this->Uploadfile->find('all', $searchoptions);
                }
                
                $upload_files = array();
                foreach ($model_uploadfiles as $singlefile) {
                    if($singlefile['Uploadfile']['fieldname'] == $v['name'] ) {
                        $upload_files[] = $singlefile['Uploadfile'];
                    }
                }
                $this->data['Uploadfile'][$v['name']] = $upload_files;                
            }
            elseif ($v['selectautoload'] && $v['selectmodel'] && in_array($v['formtype'], array('select', 'checkbox', 'radio'))) {
                $selectmodel_name = Inflector::classify($v['selectmodel']);
                if ($selectmodel_name != $this->modelClass) {
                    $this->loadModel($selectmodel_name);
                }
                // 包含deleted字段时，查询deleted为0的数据，即未删除数据
                $model_fields = array_keys($this->{$selectmodel_name}->schema());
                
                $conditions = array();
                $xml_oprions = xml_to_array($v['conditions']);    
                if(isset($xml_oprions['options']['conditions'])){
                    $conditions = $xml_oprions['options']['conditions'];
                }

                if ($v['formtype'] == 'select' && $v['name'] != 'status') {
                    $newoptions = array('' => __('Please select'));
                } else {
                    $newoptions = array();
                }
                /**
                 * 树类型的模型
                 */
                if (isset($this->{$selectmodel_name}->actsAs['Tree'])) {
                    $this->{$selectmodel_name}->recursive = 1;
                    if ($v['associatetype'] == 'treenode') {
                        if ($v['selectparentid']) {
                            $rootcate = $this->{$selectmodel_name}->findById($v['selectparentid']);
                            $conditions['left >'] = $left = $rootcate[$selectmodel_name]['left'];
                            $conditions['right <'] = $right = $rootcate[$selectmodel_name]['right'];
                            $options = $this->{$selectmodel_name}->generateTreeList($conditions,null,null,'__',1);
                        } else {
                            $options = $this->{$selectmodel_name}->generateTreeList($conditions,null,null,'__',1);
                        }
                        // print_r($options);
                        foreach ($options as $ok => $ov) {
                            $newoptions[$ok] = $ov;
                        }
                    } else {
                        // 只显示一级的情况
//                      $option_result = $this->{$selectmodel_name}->children($v['selectparentid'], true);
                        if($v['selectparentid']){
                            $conditions['parent_id'] = $v['selectparentid'];
                        }
                        else{
                            $conditions['parent_id'] = NULL;
                        }
                        
                        

                        $option_result = $this->{$selectmodel_name}->find('all', array(
                                    'conditions' => $conditions,
                                    'order' => $selectmodel_name . '.id ASC',
                                    'limit' => 100,
                                    'page' => 1,
                                    'fields' => array(
                                        $v['selectvaluefield'], $v['selecttxtfield'],
                                    ),
                                ));

                        foreach ($option_result as $option) {
                            $optionvalue = $option[$selectmodel_name][$v['selectvaluefield']];
                            $optiontxt = $option[$selectmodel_name][$v['selecttxtfield']];
                            $newoptions[$optionvalue] = $optiontxt;
                        }
                    }
                } else {
                    $option_result = $this->{$selectmodel_name}->find('all', array(
                                'conditions' => $conditions,
                                'order' => $selectmodel_name . '.id ASC',
                                'limit' => 200,
                                'page' => 1,
                                'fields' => array(
                                    $v['selectvaluefield'], $v['selecttxtfield'],
                                ),
                            ));
                    foreach ($option_result as $option) {
                        $optionvalue = $option[$selectmodel_name][$v['selectvaluefield']];
                        $optiontxt = $option[$selectmodel_name][$v['selecttxtfield']];
                        $newoptions[$optionvalue] = $optiontxt;
                    }
                }
                $fieldname = Inflector::variable(
                    Inflector::pluralize(preg_replace('/_id$/', '', $k))
                );
                $this->set($fieldname, $newoptions);
            }
        }
    }

}
?>
